import axios, {AxiosRequestConfig} from 'axios';
import {InterfaceResponse} from '@/interface/InterfaceResponse';
import CommonUnit from '@/unit/CommonUnit';

// axios.interceptors.request.use((config: AxiosRequestConfig) => {
//     if (config.method === 'post') {
//         const qs = require('qs');
//         config.data = qs.stringify(config.data);
//     }
//     return config;
// });


export default class Http {

    public static async post(url: string, obj: any = {}, header = {}): Promise<InterfaceResponse> {
        const qs = require('qs');
        const promise = new Promise<PromiseLike<any>>((resolve, reject) => {
            axios.post(`${url}?_self=${Date.parse(new Date().toString())}`, qs.stringify(obj), {headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', ...header}}).then((res: any) => {
                let data = res.data;
                if (!data.hasOwnProperty('code')) {
                    data = {code: 0, msg: 'Response is not a valid JSON format'};
                }
                resolve(data);
            }).catch((error: any) => {
                reject(error);
            });
        });
        return promise;
    }

    public static async get(url: string, obj: any = {}, header = {}): Promise<InterfaceResponse> {
        obj._self = Date.parse(new Date().toString());
        let parameter: string = Object.keys(obj).length > 0 ? '?' : '';
        parameter = parameter + Object.keys(obj)
            .map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`)
            .join('&');
        const promise = new Promise<PromiseLike<any>>((resolve, reject) => {
            axios.get(`${url}${(parameter)}`, {headers: header}).then((res: any) => {
                let data = res.data;
                if (!data.hasOwnProperty('code')) {
                    data = {code: 0, msg: 'Response is not a valid JSON format'};
                }
                resolve(data);
            }).catch((error: any) => {
                reject(error);
            });
        });
        return promise;
    }

    public static async upload(url: string, obj: any = {}, header = {}): Promise<InterfaceResponse> {
        const formData = new FormData();
        for (const key of Object.keys(obj)) {
            formData.append(key, obj[key]);
        }
        const promise = new Promise<PromiseLike<any>>((resolve, reject) => {
            const instance = axios.create({withCredentials: true});
            instance.post(`${url}?_self=${Date.parse(new Date().toString())}`, formData, {
                headers: {...header},
                onUploadProgress: (progressEvent: ProgressEvent) => {
                    const progressNum: number = (progressEvent.loaded / progressEvent.total) * 100;
                },
            }).then((res: any) => {
                resolve(res.data);
            }).catch((error: any) => {
                reject(error);
            });
        });
        return promise;
    }

    public static async read(url: string, obj: any = {}, header = {}): Promise<any> {
        obj._self = Date.parse(new Date().toString());
        let parameter: string = Object.keys(obj).length > 0 ? '?' : '';
        parameter = parameter + Object.keys(obj)
            .map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`)
            .join('&');
        const promise = new Promise<PromiseLike<any>>((resolve, reject) => {
            axios.get(`${url}${(parameter)}`, {headers: {...header}}).then((res: any) => {
                resolve(res.data);
            }).catch((error: any) => {
                reject(error);
            });
        });
        return promise;
    }

    // public static async uploadNative(url: string, fileUrl: string = '', obj: any = {}, header = {}): Promise<InterfaceResponse> {
    //     const formData = new FormData();
    //     for (const key of Object.keys(obj)) {
    //         formData.append(key, obj[key]);
    //     }
    //     const promise = new Promise<PromiseLike<any>>((resolve, reject) => {
    //         const fileUploadOptions: any = new FileUploadOptions();
    //         const fileTransfer: any = new FileTransfer();
    //         fileUploadOptions.fileKey = 'iFile';
    //         fileUploadOptions.headers = header;
    //         fileUploadOptions.params = obj;
    //         fileTransfer.upload(fileUrl, encodeURI(url), (res: any) => {
    //             const data: InterfaceResponse | any = {code: 0, msg: 'Response is not a valid JSON format', data: res};
    //             try {
    //                 const result = JSON.parse(res.response);
    //                 resolve(result);
    //             } catch (e) {
    //                 resolve(data);
    //             }
    //         }, (error: any) => {
    //             reject(error);
    //         }, fileUploadOptions);
    //
    //     });
    //     return promise;
    // }

    private static code: string = '123456';
    private static version: number = 1;
    private static str: string = CommonUnit.getRandomString();

    private static header(header: any = {}, params: any = {}): any {
        const defaultHeader: any = {
            code: this.code,
            version: this.version,
            str: this.str,
            time: Date.parse(new Date().toString()),
        };
        // tslint:disable-next-line:forin
        for (const i in params) {
            params[i] = encodeURI(params[i]);
        }
        params = Object.assign(defaultHeader, header, params);
        const paramsKey = Object.keys(params).sort();
        const paramsArray = [];
        // tslint:disable-next-line:forin
        for (const i in paramsKey) {
            paramsArray.push(`${paramsKey[i]}=${encodeURI(params[paramsKey[i]])}`);
        }
        const md5 = require('js-md5');
        return {
            ...Object.assign(defaultHeader, header),
            encryption: encodeURI(md5(paramsArray.join('&'))),
        };

    }
}
